package com.ikingtech.framework.sdk.workbench.embedded.aspect;

import com.ikingtech.framework.sdk.base.model.BatchParam;
import com.ikingtech.framework.sdk.context.security.Me;
import com.ikingtech.framework.sdk.utils.SpEL;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.framework.sdk.workbench.api.TodoTaskApi;
import com.ikingtech.framework.sdk.workbench.embedded.annotation.Todo;
import com.ikingtech.framework.sdk.workbench.model.TodoTaskDTO;
import com.ikingtech.framework.sdk.workbench.model.TodoTaskDeleteBatchParamDTO;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;

import java.util.ArrayList;
import java.util.List;

/**
 * @author tie yan
 */
@Aspect
@RequiredArgsConstructor
public class TodoAspect {

    private final TodoTaskApi api;

    @After(value = "@annotation(todo)")
    public void doAfter(JoinPoint joinPoint, Todo todo) {
        SpEL spEl = SpEL.init(((MethodSignature) joinPoint.getSignature()).getMethod(), joinPoint.getArgs());
        List<String> appendUserIds = new ArrayList<>();
        List<String> completeUserIds = new ArrayList<>();
        if (todo.appendUser().loginUser()) {
            appendUserIds.add(Me.id());
        } else {
            appendUserIds.addAll(this.parseUser(spEl, todo.appendUser().userId()));
        }
        if (todo.completeUser().loginUser()) {
            completeUserIds.add(Me.id());
        } else {
            if (Tools.Str.isNotBlank(todo.completeUser().userId())) {
                completeUserIds.addAll(this.parseUser(spEl, todo.completeUser().userId()));
            }
        }
        String businessName = (String) spEl.parse(todo.businessName());
        String summary = (String) spEl.parse(todo.summary());
        String redirectLinkParam = (String) spEl.parse(todo.redirect().param());
        String businessId = (String) spEl.parse(todo.businessId());
        TodoTaskDeleteBatchParamDTO deleteParam = new TodoTaskDeleteBatchParamDTO();
        deleteParam.setBusinessId(businessId);
        deleteParam.setUserIds(completeUserIds);
        this.api.deleteBatch(deleteParam);
        List<TodoTaskDTO> newTasks = new ArrayList<>();
        for (String appendUserId : appendUserIds) {
            TodoTaskDTO task = new TodoTaskDTO();
            task.setBusinessName(businessName);
            task.setBusinessId(businessId);
            task.setSummary(summary);
            task.setStatus(todo.status());
            task.setRedirect(Tools.Str.format("{}/{}", todo.redirect().link(), redirectLinkParam));
            task.setUserId(appendUserId);
            task.setAppCode(todo.appCode());
            newTasks.add(task);
        }
        this.api.addBatch(BatchParam.build(newTasks));
    }

    private List<String> parseUser(SpEL spEl, String userIdsExpression) {
        Object userIds = spEl.parse(userIdsExpression);
        if (userIds instanceof List) {
            return Tools.Obj.list(userIds);
        }
        if (userIds instanceof String) {
            return Tools.Str.split((String) userIds);
        }
        return new ArrayList<>();
    }
}
